package lk.icta.core.service;

import lk.icta.core.dto.AlienationDetails;
import lk.icta.core.entity.Alienation;
import lk.icta.core.entity.AlienationMethod;
import lk.icta.core.entity.LandAssociation;
import lk.icta.user.entity.User;

import java.util.List;
import java.util.Map;

public interface AlienationManagementService {

    /**
     * Add an initial alienation
     *
     * @param alienation Alienation to be added
     * @param user       User requesting to add alienation
     */
    public void addInitialAlienation(Alienation alienation, User user);

    /**
     * Adding a detail Alienation
     *
     * @param alienation Alienation to be added
     * @param user       User requesting to add alienation
     */
    public void addDetailAlienation(Alienation alienation, User user);

    /**
     * Updating a detail alienation
     *
     * @param alienation Alienation to be updated
     * @param user       User requesting to update alienation
     */
    public void updateDetailAlienation(Alienation alienation, User user);

    /**
     * Deleting a detail alienation
     *
     * @param alienation Alienation to be deleted
     * @param user       User requesting to delete alienation
     */
    public void deleteDetailAlienation(Alienation alienation, User user);

    public void deleteAlienationFromDatabase(long alienationId, User user);

    /**
     * Update an alienation
     *
     * @param alienation Alienation to be updated
     * @param user       The user requesting to update the alienation
     */
    public void updateAlienation(Alienation alienation, User user);

    /**
     * Adding a mortgage to the alienation
     *
     * @param alienation Alienation with the mortgage
     * @param user       User requesting to add mortgage
     */
    public void addMortgage(Alienation alienation, User user);

    /**
     * Approve an alienation
     *
     * @param alienation Alienation to be approved
     * @param user       User requesting to approve the alienation
     */
    public void approveAlienation(Alienation alienation, User user);

    /**
     * Rejecting an alienation
     *
     * @param alienation Alienation to be rejected
     * @param user       User requesting to reject the alienation
     */
    public void rejectAlienation(Alienation alienation, User user);

    /**
     * Add Land Alienation Methods to lands
     *
     * @param LAMMetadata Alienation Metadeta to be persist
     * @param user        user who performs this action
     */
    public void addLandAlienationMetadata(LandAssociation LAMMetadata, User user);

    /**
     * Find alienation method by alienation Id
     *
     * @param id   Alienation Id
     * @param user user who performs this action
     * @return The Alienation Method corresponding to the given id
     */
    public AlienationMethod getAlienationMethodById(int id, User user);

    /**
     * Return Alienation history tree by the root land id
     *
     * @param rootId Root land id
     * @param user   User requesting to list alienation history
     * @return Alienation history tree
     */
    public List<Alienation> getAlienationHistoryByRootLandId(long rootId, User user);

    public List<AlienationDetails> getAlienationHistoryByGrantId(long grantId, User user);

    /**
     * Find alienation by Alienation Id
     *
     * @param id   The Alienation Id
     * @param user The user requesting to find the alienation
     * @return An alienation corresponding to the given id
     */
    public Alienation getAlienationById(Long id, User user);

    /**
     * List all active alienation records
     *
     * @param user User requesting to list alienation
     * @return List of all active alienation
     */
    public List<Alienation> getAllActiveAlienation(User user);

    /**
     * Returns the  Alienation of the land
     *
     * @param landId Id of the land
     * @param user   User requesting to find the alienation
     * @return Alienation of the land
     */
    public List<Alienation> getAlienationByLand(long landId, User user);

    /**
     * Returns the ACTIVE Alienation of the land
     *
     * @param landId Id of the land
     * @param user   User requesting to find the alienation
     * @return ACTIVE Alienation of the land
     */
    public Alienation getActiveAlienationByLandId(long landId, User user);

    public Alienation getPendingAlienationByLandId(long landId, User user);

    /**
     * Returns list of children alienation of given alienation
     *
     * @param parentId Id of the alienation
     * @param user     User requesting to list children
     * @return List of child nodes
     */
    public List<Alienation> getAllChildNodesByParentId(long parentId, User user);

    /**
     * Returns list of alienation related to given alienation method
     *
     * @param alienationMethod Alienation method
     * @param user             User requesting to list alienation
     * @return List of alienation
     */
    public List<Alienation> getAlienationByAlienationMethod(int alienationMethod, User user);

    public List<Alienation> getAllAlienationByAlienationMethod(int alienationMethod, User user);

    /**
     * Returns All Alienation Methods
     *
     * @param language the selected language
     * @param user     the user requesting the full District name list
     * @return a Map of all Alienation Methods for the given language
     */
    public Map<Integer, String> getAllAlienationMethods(String language, User user);

    /**
     * Returns All Alienation Methods for public
     *
     * @param language the selected language
     * @return a Map of all Alienation Methods for the given language
     */
    public Map<Integer, String> getAllAlienationMethods(String language);

    /**
     * Returns the ACTIVE Alienation of the permit no
     *
     * @param permitNo permit number of the alienation
     * @param user     User requesting to find the alienation
     * @return ACTIVE Alienation of the land
     */
    public Alienation getActiveAlienationByPermitNo(String permitNo, User user);

    /**
     * Returns the ACTIVE Approved Alienation of the permit no
     *
     * @param permitNo permit number of the alienation
     * @param user     User requesting to find the alienation
     * @return ACTIVE Alienation of the land
     */
    public Alienation getActiveApprovedAlienationByPermitNo(String permitNo, User user);


    /**
     * Check whether an alienation exists with the given reference
     *
     * @param referenceNo Reference no to be checked
     * @param user        User requesting the checkup
     * @return TRUE if reference exists. FALSE otherwise
     */
    public Boolean isExistsReference(String referenceNo, User user);

    public List<Alienation> getAllAlienation(User user);

    public List<Alienation> searchPermitLands(User user);

    /**
     * Returns the State=Pending Alienation of the alienation id
     *
     * @param alienationId permit number of the alienation
     * @return Pending Alienation of the land
     */
    public List<Alienation> getPendingAlienationsByAlienationMethod(int alienationId, User user);
}
